package utils

import (
	"fmt"
	"golang.org/x/net/html"
	"regexp"
	"strings"
)

var REG_CMT = regexp.MustCompile("(?s)<!--cmt_start-->.*<!--cmt_end-->")

func AsBook(content string, title string) string {
	title = "<h2 class=\"rich_media_title \" id=\"activity-name\">" + title + "</h2>"
	doc, _ := html.Parse(strings.NewReader(content))
	imgContent := findElementById(doc, "js_content")
	innerHtml := extractInnerHTML(imgContent)
	innerHtml = "<div class=\"rich_media_content js_underline_content autoTypeSetting24psection\" id=\"js_content\" style=\"visibility: visible;\" deep=\"5\">" + innerHtml + "</div>"
	submatch := REG_CMT.FindAllStringSubmatch(content, 1)
	if len(submatch) == 1 {
		return title + innerHtml + submatch[0][0]
	} else {
		return title + innerHtml
	}
}

// Find the first element with the given ID
func findElementById(n *html.Node, id string) *html.Node {
	if n.Type == html.ElementNode && n.Attr != nil {
		for _, attr := range n.Attr {
			if attr.Key == "id" && attr.Val == id {
				return n
			}
		}
	}
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		if result := findElementById(c, id); result != nil {
			return result
		}
	}
	return nil
}

// Extract the inner HTML of the element
func extractInnerHTML(n *html.Node) string {
	var h string
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		h += renderNode(c)
	}
	return h
}

// Render a node as an HTML string
func renderNode(n *html.Node) string {
	var h string
	switch n.Type {
	case html.ErrorNode:
		h = fmt.Sprintf("<!--%s-->", n.Data)
	case html.TextNode:
		h = n.Data
	case html.DocumentNode, html.ElementNode:
		h = fmt.Sprintf("<%s", n.Data)
		for _, a := range n.Attr {
			h += fmt.Sprintf(` %s="%s"`, a.Key, a.Val)
		}
		if n.Type == html.ElementNode {
			h += ">"
		}
		for c := n.FirstChild; c != nil; c = c.NextSibling {
			h += renderNode(c)
		}
		if n.Type == html.ElementNode {
			h += fmt.Sprintf("</%s>", n.Data)
		}
	case html.CommentNode:
		h = fmt.Sprintf("<!--%s-->", n.Data)
	}
	return h
}
